﻿using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections;
using System.IO;
using System.Runtime.CompilerServices;

namespace APP.HELPER.Utils.Zip

{
    public class ZipHelper
    {
        public delegate void UnzipProcessEventHander(object sender, long position);
        public delegate void UnzipFailEventHander(object sender, string Message);
        public delegate void UnzipCompleteEventHander(object sender);
        public static event ZipHelper.UnzipProcessEventHander UnzipProcess;
        public static event ZipHelper.UnzipFailEventHander UnzipFail;
        public static event ZipHelper.UnzipCompleteEventHander UnzipComplete;
        public static byte[] CompressFolder(string folderPath)
        {
            byte[] result;
            if (folderPath == null || folderPath.Length <= 0)
            {
                result = null;
            }
            else
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (ZipOutputStream zipOutputStream = new ZipOutputStream(memoryStream))
                    {
                        Crc32 crc = new Crc32();
                        zipOutputStream.SetLevel(9);
                        ZipHelper.DoCompressFolder(memoryStream, zipOutputStream, crc, folderPath, folderPath);
                        zipOutputStream.Finish();
                        byte[] array = new byte[memoryStream.Length];
                        memoryStream.Seek(0L, SeekOrigin.Begin);
                        memoryStream.Read(array, 0, array.Length);
                        zipOutputStream.Close();
                        result = array;
                    }
                }
            }
            return result;
        }
        private static void DoCompressFolder(MemoryStream buf, ZipOutputStream zip, Crc32 crc, string baseFolderPath, string currentFolderPath)
        {
            string[] array = Directory.GetFiles(currentFolderPath);
            for (int i = 0; i < array.Length; i++)
            {
                string text = array[i];
                string name = text.Substring(baseFolderPath.Length).Trim(new char[]
				{
					'\\'
				});
                using (FileStream fileStream = new FileStream(text, FileMode.Open, FileAccess.Read))
                {
                    using (new BinaryReader(fileStream))
                    {
                        byte[] array2 = new byte[fileStream.Length];
                        fileStream.Read(array2, 0, array2.Length);
                        ZipEntry zipEntry = new ZipEntry(name);
                        zipEntry.DateTime = DateTime.Now;
                        zipEntry.Size = (long)array2.Length;
                        crc.Reset();
                        crc.Update(array2);
                        zipEntry.Crc = crc.Value;
                        zip.PutNextEntry(zipEntry);
                        zip.Write(array2, 0, array2.Length);
                    }
                }
            }
            array = Directory.GetDirectories(currentFolderPath);
            for (int i = 0; i < array.Length; i++)
            {
                string currentFolderPath2 = array[i];
                ZipHelper.DoCompressFolder(buf, zip, crc, baseFolderPath, currentFolderPath2);
            }
        }
        public static void DecompressFolder(byte[] input, string folderPath)
        {
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }
            using (MemoryStream memoryStream = new MemoryStream(input))
            {
                using (ZipInputStream zipInputStream = new ZipInputStream(memoryStream))
                {
                    ZipEntry nextEntry;
                    while ((nextEntry = zipInputStream.GetNextEntry()) != null)
                    {
                        using (MemoryStream memoryStream2 = new MemoryStream())
                        {
                            byte[] array = new byte[4096];
                            while (true)
                            {
                                int num = zipInputStream.Read(array, 0, array.Length);
                                if (num <= 0)
                                {
                                    break;
                                }
                                memoryStream2.Write(array, 0, num);
                            }
                            string path = Path.Combine(folderPath, nextEntry.Name);
                            if (!Directory.Exists(Path.GetDirectoryName(path)))
                            {
                                Directory.CreateDirectory(Path.GetDirectoryName(path));
                            }
                            if (File.Exists(path))
                            {
                                File.Delete(path);
                            }
                            using (BinaryReader binaryReader = new BinaryReader(memoryStream2))
                            {
                                using (FileStream fileStream = new FileStream(path, FileMode.CreateNew, FileAccess.Write))
                                {
                                    using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
                                    {
                                        byte[] buffer = new byte[memoryStream2.Length];
                                        memoryStream2.Seek(0L, SeekOrigin.Begin);
                                        binaryReader.Read(buffer, 0, (int)memoryStream2.Length);
                                        binaryWriter.Write(buffer);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public static void ZipFiles(string inputFolderPath, string outputPathAndFile)
        {
            ArrayList arrayList = ZipHelper.GenerateFileList(inputFolderPath);
            int num = Directory.GetParent(inputFolderPath).ToString().Length;
            num++;
            string path = inputFolderPath + "\\" + outputPathAndFile;
            ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(path));
            zipOutputStream.SetLevel(9);
            foreach (string text in arrayList)
            {
                ZipEntry entry = new ZipEntry(text.Remove(0, num));
                zipOutputStream.PutNextEntry(entry);
                if (!text.EndsWith("/"))
                {
                    FileStream fileStream = File.OpenRead(text);
                    byte[] array = new byte[fileStream.Length];
                    fileStream.Read(array, 0, array.Length);
                    zipOutputStream.Write(array, 0, array.Length);
                }
            }
            zipOutputStream.Finish();
            zipOutputStream.Close();
        }
        private static void RaiseUnzipProcessEventHander(long position)
        {
            if (ZipHelper.UnzipProcess != null)
            {
                ZipHelper.UnzipProcess(null, position);
            }
        }
        private static void RaiseUnzipFailEventHander(string Message)
        {
            if (ZipHelper.UnzipFail != null)
            {
                ZipHelper.UnzipFail(null, Message);
            }
        }
        private static void RaiseUnzipCompleteEventHander()
        {
            if (ZipHelper.UnzipComplete != null)
            {
                ZipHelper.UnzipComplete(null);
            }
        }
        public static string Unzipfile(string ZipPath, string UnzipPath)
        {
            string result;
            try
            {
                ZipHelper.RaiseUnzipProcessEventHander(0L);
                ZipInputStream zipInputStream = new ZipInputStream(File.OpenRead(ZipPath));
                FileStream fileStream = null;
                string text = "";
                long num = 0L;
                ZipEntry nextEntry;
                while ((nextEntry = zipInputStream.GetNextEntry()) != null)
                {
                    string text2 = "";
                    try
                    {
                        text2 = Path.GetDirectoryName(nextEntry.Name);
                        if (!Directory.Exists(UnzipPath + "\\" + text2))
                        {
                            Directory.CreateDirectory(UnzipPath + "\\" + text2);
                        }
                    }
                    catch (Exception ex)
                    {
                        ZipHelper.RaiseUnzipFailEventHander(ex.Message);
                        result = "";
                        return result;
                    }
                    text = Path.GetFileName(nextEntry.Name);
                    try
                    {
                        if (text != string.Empty)
                        {
                            fileStream = File.Create(string.Concat(new string[]
							{
								UnzipPath,
								"\\",
								text2,
								"\\",
								text
							}));
                            byte[] array = new byte[20480];
                            while (true)
                            {
                                int num2 = zipInputStream.Read(array, 0, array.Length);
                                num += (long)num2;
                                ZipHelper.RaiseUnzipProcessEventHander(num / nextEntry.Size * 100L);
                                if (num2 <= 0)
                                {
                                    break;
                                }
                                fileStream.Write(array, 0, num2);
                            }
                            fileStream.Close();
                        }
                    }
                    catch (Exception ex)
                    {
                        ZipHelper.RaiseUnzipFailEventHander(ex.Message);
                        result = "";
                        return result;
                    }
                }
                if (fileStream != null)
                {
                    fileStream.Close();
                }
                zipInputStream.Close();
                ZipHelper.RaiseUnzipCompleteEventHander();
                result = text;
            }
            catch (Exception ex)
            {
                ZipHelper.RaiseUnzipFailEventHander(ex.Message);
                result = ex.Message;
            }
            return result;
        }
        private static ArrayList GenerateFileList(string Dir)
        {
            ArrayList arrayList = new ArrayList();
            bool flag = true;
            string[] array = Directory.GetFiles(Dir);
            for (int i = 0; i < array.Length; i++)
            {
                string value = array[i];
                arrayList.Add(value);
                flag = false;
            }
            if (flag)
            {
                if (Directory.GetDirectories(Dir).Length == 0)
                {
                    arrayList.Add(Dir + "/");
                }
            }
            array = Directory.GetDirectories(Dir);
            for (int i = 0; i < array.Length; i++)
            {
                string dir = array[i];
                foreach (object current in ZipHelper.GenerateFileList(dir))
                {
                    arrayList.Add(current);
                }
            }
            return arrayList;
        }
        public static string CompressFolder(string srcDir, string destZipFile, string filter)
        {
            DateTime now = DateTime.Now;
            ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(destZipFile));
            ZipHelper.AddFilesFoldersToZip(srcDir, srcDir, filter, ref zipOutputStream);
            zipOutputStream.Finish();
            zipOutputStream.Flush();
            zipOutputStream.Close();
            DateTime now2 = DateTime.Now;
            return (now2 - now).TotalMilliseconds.ToString("F") + "ms";
        }
        public static void AddFilesFoldersToZip(string srcDir, string rootDir, string filter, ref ZipOutputStream zos)
        {
            string[] array = Directory.GetFiles(srcDir, filter);
            for (int i = 0; i < array.Length; i++)
            {
                string text = array[i];
                zos.SetLevel(9);
                FileInfo fileInfo = new FileInfo(text);
                ZipEntry zipEntry = new ZipEntry(srcDir.Remove(0, rootDir.Length) + "\\" + fileInfo.Name);
                FileStream fileStream = File.OpenRead(text);
                byte[] array2 = new byte[Convert.ToInt32(fileStream.Length)];
                fileStream.Read(array2, 0, (int)fileStream.Length);
                zipEntry.DateTime = fileInfo.LastWriteTime;
                zipEntry.Size = fileStream.Length;
                fileStream.Close();
                zos.PutNextEntry(zipEntry);
                zos.Write(array2, 0, array2.Length);
            }
            array = Directory.GetDirectories(srcDir);
            for (int i = 0; i < array.Length; i++)
            {
                string srcDir2 = array[i];
                ZipHelper.AddFilesFoldersToZip(srcDir2, rootDir, filter, ref zos);
            }
        }
        public static string Decompress(string zipFile, string destDir)
        {
            DateTime now = DateTime.Now;
            ZipInputStream zipInputStream = new ZipInputStream(File.OpenRead(zipFile));
            ZipEntry nextEntry;
            while ((nextEntry = zipInputStream.GetNextEntry()) != null)
            {
                string text = Path.Combine(destDir, nextEntry.Name);
                FileInfo fileInfo = new FileInfo(text);
                if (!Directory.Exists(fileInfo.DirectoryName))
                {
                    Directory.CreateDirectory(fileInfo.DirectoryName);
                }
                FileStream fileStream = File.Create(text);
                long num = nextEntry.Size;
                byte[] array = new byte[num];
                while (true)
                {
                    num = (long)zipInputStream.Read(array, 0, array.Length);
                    if (num <= 0L)
                    {
                        break;
                    }
                    fileStream.Write(array, 0, (int)num);
                }
                fileStream.Close();
            }
            DateTime now2 = DateTime.Now;
            return (now2 - now).TotalMilliseconds.ToString("F") + "ms";
        }
        public static void CompressFile(string sPath, string descZipFile)
        {
            ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(descZipFile));
            FileInfo fileInfo = new FileInfo(sPath);
            ZipEntry zipEntry = new ZipEntry(fileInfo.Name);
            FileStream fileStream = File.OpenRead(sPath);
            byte[] array = new byte[Convert.ToInt32(fileStream.Length)];
            fileStream.Read(array, 0, (int)fileStream.Length);
            zipEntry.DateTime = fileInfo.LastWriteTime;
            zipEntry.Size = fileStream.Length;
            fileStream.Close();
            zipOutputStream.PutNextEntry(zipEntry);
            zipOutputStream.Write(array, 0, array.Length);
            zipOutputStream.Finish();
            zipOutputStream.Close();
        }
        public static void UncompressFile(string zipFile, string destDir)
        {
            ZipInputStream zipInputStream = new ZipInputStream(File.OpenRead(zipFile));
            ZipEntry nextEntry;
            while ((nextEntry = zipInputStream.GetNextEntry()) != null)
            {
                FileStream fileStream = File.Create(destDir + "\\" + nextEntry.Name);
                long num = nextEntry.Size;
                byte[] array = new byte[num];
                while (true)
                {
                    num = (long)zipInputStream.Read(array, 0, array.Length);
                    if (num <= 0L)
                    {
                        break;
                    }
                    fileStream.Write(array, 0, (int)num);
                }
                fileStream.Close();
            }
            Console.WriteLine("Done!!");
        }
    }
}
